{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d760e6e6",
   "metadata": {},
   "source": [
    "# Entropic Portfolio Optimization\n",
    "\n",
    "In this notebook we show how to use the exponential cone to model the perspective of the `log_sum_exp` function and its application in portfolio optimization.\n",
    "\n",
    "## 1. Entropic Value at Risk Optimization\n",
    "\n",
    "### 1.1 The Entropic Value at Risk\n",
    "\n",
    "The Entropic Value at Risk (EVaR) which is a new risk measure introduced by __[Ahmadi-Javid (2012)](https://link.springer.com/article/10.1007/s10957-011-9968-2?r=1&l=ri&fst=0&error=cookies_not_supported&code=ccfb8a5e-692b-43d1-b76e-ae596c7f0bed)__. It is the upper bound based on Chernoff Inequality of Value at Risk (VaR) and Conditional Value at Risk (CVaR), formally it is defined as:\n",
    "\n",
    "$$\n",
    "\\text{EVaR}_{\\alpha}(X) = \\inf_{z>0} \\left \\{z\\log \\left ( \\frac{1}{\\alpha} M_{X} (\\frac{1}{z}) \\right ) \\right \\}\n",
    "$$\n",
    "\n",
    "Where $M_{X} (t) = \\text{E} [e^{tX}]$ is the moment generating function and $\\alpha \\in [0,1]$ is the significance level.\n",
    "\n",
    "### 1.2 EVaR Minimization\n",
    "\n",
    "To discretize the EVaR we need the perspective of the `log_sum_exp` function, we can do this using the exponential cone in CVXPY. The discipined convex programming (DCP) problem of EVaR minimization was proposed by __[Cajas (2021)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3792520)__ and it is posed as:\n",
    "\n",
    "$$\n",
    "\\begin{equation}\n",
    "\\begin{aligned}\n",
    "& \\underset{x, \\, z, \\, t, \\, u}{\\text{min}} & &  t + z \\ln \\left (  \\frac{1}{\\alpha T} \\right ) \\\\\n",
    "& \\text{s.t.} & & \\mu x^{\\tau} \\geq \\bar{\\mu} \\\\\n",
    "& & &  \\sum_{i=1}^{N} x_i = 1 \\\\\n",
    "& & & z \\geq \\sum^{T}_{j=1} u_{j} \\\\\n",
    "& & & (-r_{j}x^{\\tau}-t, z, u_{j}) \\in K_{\\text{exp}} \\; \\forall \\; j=1, \\ldots, T \\\\\n",
    "& & &  x_i \\geq 0 \\; ; \\; \\forall \\; i =1, \\ldots, N \\\\\n",
    "\\end{aligned}\n",
    "\\end{equation}\n",
    "$$\n",
    "\n",
    "Where $t$ is an auxiliar variable that represents the perspectives of the `log_sum_exp` function, $z$ is the factor of perspective function, $u_{j}$ is an auxiliary variable, $x$ are the weights of assets, $\\mu$ is the mean vector of expected returns, $\\bar{\\mu}$ the minimum expected return of portfolio, $K_{\\text{exp}}$ is an exponential cone and $r$ is the matrix of observed returns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2a19278a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[*********************100%***********************]  14 of 14 completed\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>BAX</th>\n",
       "      <th>BMY</th>\n",
       "      <th>CMCSA</th>\n",
       "      <th>CNP</th>\n",
       "      <th>CPB</th>\n",
       "      <th>GE</th>\n",
       "      <th>GOOG</th>\n",
       "      <th>MO</th>\n",
       "      <th>MSFT</th>\n",
       "      <th>NI</th>\n",
       "      <th>SEE</th>\n",
       "      <th>T</th>\n",
       "      <th>TGT</th>\n",
       "      <th>VZ</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2016-01-05</th>\n",
       "      <td>0.4036%</td>\n",
       "      <td>1.9693%</td>\n",
       "      <td>0.0180%</td>\n",
       "      <td>0.9305%</td>\n",
       "      <td>0.3678%</td>\n",
       "      <td>0.0977%</td>\n",
       "      <td>0.0998%</td>\n",
       "      <td>2.0213%</td>\n",
       "      <td>0.4562%</td>\n",
       "      <td>1.5881%</td>\n",
       "      <td>0.9758%</td>\n",
       "      <td>0.6987%</td>\n",
       "      <td>1.7539%</td>\n",
       "      <td>1.3735%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-06</th>\n",
       "      <td>0.2412%</td>\n",
       "      <td>-1.7556%</td>\n",
       "      <td>-0.7727%</td>\n",
       "      <td>-1.2473%</td>\n",
       "      <td>-0.1736%</td>\n",
       "      <td>-1.5940%</td>\n",
       "      <td>0.1400%</td>\n",
       "      <td>1.0589%</td>\n",
       "      <td>-1.8165%</td>\n",
       "      <td>0.5548%</td>\n",
       "      <td>-1.5647%</td>\n",
       "      <td>-0.1466%</td>\n",
       "      <td>-1.0155%</td>\n",
       "      <td>-0.9034%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-07</th>\n",
       "      <td>-1.6573%</td>\n",
       "      <td>-2.7699%</td>\n",
       "      <td>-1.1047%</td>\n",
       "      <td>-1.9769%</td>\n",
       "      <td>-1.2207%</td>\n",
       "      <td>-4.2314%</td>\n",
       "      <td>-2.3170%</td>\n",
       "      <td>-1.7408%</td>\n",
       "      <td>-3.4783%</td>\n",
       "      <td>-2.2066%</td>\n",
       "      <td>-3.1557%</td>\n",
       "      <td>-1.6148%</td>\n",
       "      <td>-0.2700%</td>\n",
       "      <td>-0.5492%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-08</th>\n",
       "      <td>-1.6037%</td>\n",
       "      <td>-2.5425%</td>\n",
       "      <td>0.1099%</td>\n",
       "      <td>-0.2241%</td>\n",
       "      <td>0.5707%</td>\n",
       "      <td>-1.7950%</td>\n",
       "      <td>-1.6410%</td>\n",
       "      <td>0.1720%</td>\n",
       "      <td>0.3067%</td>\n",
       "      <td>-0.1539%</td>\n",
       "      <td>-0.1448%</td>\n",
       "      <td>0.0895%</td>\n",
       "      <td>-3.3838%</td>\n",
       "      <td>-0.9719%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2016-01-11</th>\n",
       "      <td>-1.6851%</td>\n",
       "      <td>-1.0215%</td>\n",
       "      <td>0.0915%</td>\n",
       "      <td>-1.1791%</td>\n",
       "      <td>0.5674%</td>\n",
       "      <td>0.4569%</td>\n",
       "      <td>0.2184%</td>\n",
       "      <td>2.0948%</td>\n",
       "      <td>-0.0573%</td>\n",
       "      <td>1.6436%</td>\n",
       "      <td>-0.1451%</td>\n",
       "      <td>1.2224%</td>\n",
       "      <td>1.4570%</td>\n",
       "      <td>0.5800%</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                BAX      BMY    CMCSA      CNP      CPB       GE     GOOG  \\\n",
       "Date                                                                        \n",
       "2016-01-05  0.4036%  1.9693%  0.0180%  0.9305%  0.3678%  0.0977%  0.0998%   \n",
       "2016-01-06  0.2412% -1.7556% -0.7727% -1.2473% -0.1736% -1.5940%  0.1400%   \n",
       "2016-01-07 -1.6573% -2.7699% -1.1047% -1.9769% -1.2207% -4.2314% -2.3170%   \n",
       "2016-01-08 -1.6037% -2.5425%  0.1099% -0.2241%  0.5707% -1.7950% -1.6410%   \n",
       "2016-01-11 -1.6851% -1.0215%  0.0915% -1.1791%  0.5674%  0.4569%  0.2184%   \n",
       "\n",
       "                 MO     MSFT       NI      SEE        T      TGT       VZ  \n",
       "Date                                                                       \n",
       "2016-01-05  2.0213%  0.4562%  1.5881%  0.9758%  0.6987%  1.7539%  1.3735%  \n",
       "2016-01-06  1.0589% -1.8165%  0.5548% -1.5647% -0.1466% -1.0155% -0.9034%  \n",
       "2016-01-07 -1.7408% -3.4783% -2.2066% -3.1557% -1.6148% -0.2700% -0.5492%  \n",
       "2016-01-08  0.1720%  0.3067% -0.1539% -0.1448%  0.0895% -3.3838% -0.9719%  \n",
       "2016-01-11  2.0948% -0.0573%  1.6436% -0.1451%  1.2224%  1.4570%  0.5800%  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "####################################\n",
    "# Downloading Data\n",
    "####################################\n",
    "!pip install --quiet yfinance\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import yfinance as yf\n",
    "import warnings\n",
    "\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "yf.pdr_override()\n",
    "pd.options.display.float_format = '{:.4%}'.format\n",
    "\n",
    "# Date range\n",
    "start = '2016-01-01'\n",
    "end = '2019-12-30'\n",
    "\n",
    "# Tickers of assets\n",
    "assets = ['TGT', 'CMCSA', 'CPB', 'MO', 'T', 'BAX', 'BMY',\n",
    "          'MSFT', 'SEE', 'VZ', 'CNP', 'NI', 'GE', 'GOOG']\n",
    "assets.sort()\n",
    "\n",
    "# Downloading data\n",
    "data = yf.download(assets, start = start, end = end)\n",
    "data = data.loc[:,('Adj Close', slice(None))]\n",
    "data.columns = assets\n",
    "\n",
    "# Calculating returns\n",
    "Y = data[assets].pct_change().dropna()\n",
    "\n",
    "display(Y.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "583f7d9a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Weights</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>BAX</th>\n",
       "      <td>5.8220%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>BMY</th>\n",
       "      <td>8.9075%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CMCSA</th>\n",
       "      <td>7.9345%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CNP</th>\n",
       "      <td>15.6326%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CPB</th>\n",
       "      <td>15.5868%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>GE</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>GOOG</th>\n",
       "      <td>4.7998%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>MO</th>\n",
       "      <td>1.8486%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>MSFT</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>NI</th>\n",
       "      <td>12.4118%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SEE</th>\n",
       "      <td>7.5494%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>T</th>\n",
       "      <td>1.1044%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>TGT</th>\n",
       "      <td>17.1416%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>VZ</th>\n",
       "      <td>1.2611%</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Weights\n",
       "BAX    5.8220%\n",
       "BMY    8.9075%\n",
       "CMCSA  7.9345%\n",
       "CNP   15.6326%\n",
       "CPB   15.5868%\n",
       "GE     0.0000%\n",
       "GOOG   4.7998%\n",
       "MO     1.8486%\n",
       "MSFT   0.0000%\n",
       "NI    12.4118%\n",
       "SEE    7.5494%\n",
       "T      1.1044%\n",
       "TGT   17.1416%\n",
       "VZ     1.2611%"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "####################################\n",
    "# Finding the Min EVaR Portfolio\n",
    "####################################\n",
    "\n",
    "import cvxpy as cp\n",
    "\n",
    "# Defining initial inputs\n",
    "mu = Y.mean().to_numpy().reshape(1,-1)\n",
    "returns = Y.to_numpy()\n",
    "n = returns.shape[0]\n",
    "\n",
    "# Defining initial variables\n",
    "w = cp.Variable((mu.shape[1], 1))\n",
    "alpha = 0.05\n",
    "ret = mu @ w\n",
    "X = returns @ w\n",
    "\n",
    "# Entropic Value at Risk Model Variables\n",
    "t = cp.Variable((1, 1))\n",
    "z = cp.Variable((1, 1), nonneg=True)\n",
    "ui = cp.Variable((n, 1))\n",
    "constraints = [cp.sum(ui) <= z,\n",
    "               cp.constraints.ExpCone(-X - t, np.ones((n, 1)) @ z, ui)] # Exponential cone constraint\n",
    "\n",
    "# Budget and weights constraints\n",
    "constraints += [cp.sum(w) == 1,\n",
    "                w >= 0]\n",
    "\n",
    "# Defining risk objective\n",
    "risk = t + z * np.log(1 / (alpha * n))\n",
    "objective = cp.Minimize(risk)\n",
    "\n",
    "# Solving problem\n",
    "prob = cp.Problem(objective, constraints)\n",
    "prob.solve()\n",
    "\n",
    "# Showing Optimal Weights\n",
    "weights = pd.DataFrame(w.value, index=assets, columns=['Weights'])\n",
    "display(weights)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3459910a",
   "metadata": {},
   "source": [
    "## 2. Entropic Drawdown at Risk Optimization\n",
    "\n",
    "### 2.1 The Entropic Drawdown at Risk\n",
    "\n",
    "The Entropic Drawdown at Risk (EDaR) which is a new risk measure introduced by __[Cajas (2021)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3792520)__. It is the upper bound based on Chernoff Inequality of Drawdown at Risk (DaR) and Conditional Drawdown at Risk (CDaR), formally it is defined as:\n",
    "\n",
    "$$\n",
    "\\begin{equation}\n",
    "\\begin{aligned}\n",
    "\\text{EDaR}_{\\alpha}(X) & =  \\text{EVaR}_{\\alpha}(\\text{DD}(X)) \\\\\n",
    "\\text{EDaR}_{\\alpha}(X) & = \\inf_{z>0} \\left \\{ z \\ln \\left (\\frac{1}{\\alpha}M_{\\text{DD}(X)} \\left (\\frac{1}{z} \\right ) \\right ) \\right \\}  \\\\\n",
    "\\end{aligned}\n",
    "\\end{equation}\n",
    "$$\n",
    "\n",
    "where $M_{X}(t)$ is the moment generating function of $t$, $\\alpha \\in [0,1]$ is the significance level and $\\text{DD}(X)$ is the drawdown of $X$.\n",
    "\n",
    "### 2.2 Maximization of Return/EDaR ratio\n",
    "\n",
    "This problem is a __[linear fractional programming](https://en.wikipedia.org/wiki/Linear-fractional_programming)__ problem and can be converted to a DCP problem using __Charnes and Cooper transformation__. The DCP problem of maximization of return EDaR ratio was proposed by __[Cajas (2021)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3792520)__ and it is posed as:\n",
    "\n",
    "$$\n",
    "\\begin{equation}\n",
    "\\begin{aligned}\n",
    "& \\underset{y, \\, k, \\, z, \\, t, \\, u, \\, d}{\\text{min}} & &   t + z \\ln \\left (  \\frac{1}{\\alpha T} \\right )\\\\\n",
    "& \\text{s.t.} & &  \\mu y^{\\tau} - r_{f} k= 1 \\\\\n",
    "& & &  \\sum_{i=1}^{N} y_{i} = k \\\\\n",
    "& & & z \\geq \\sum^{T}_{j=1} u_{j} \\\\\n",
    "& & & (d_{j} - R_{j} y^{\\tau} - t, z, u_{j}) \\in K_{\\text{exp}} \\; \\forall \\; j =1, \\ldots, T \\\\\n",
    "& & & d_{j} \\geq R_{j} y^{\\tau} \\; \\forall \\; j=1, \\ldots, T \\\\ \n",
    "& & & d_{j} \\geq d_{j-1}  \\; \\forall \\; j=1, \\ldots, T \\\\ \n",
    "& & & d_{j} \\geq 0  \\; \\forall \\; j=1, \\ldots, T \\\\ \n",
    "& & & d_{0} = 0 \\\\ \n",
    "& & &  k \\geq 0 \\\\\n",
    "& & &  y_{i} \\geq 0 \\; ; \\; \\forall \\; i =1, \\ldots, N \\\\\n",
    "\\end{aligned}\n",
    "\\end{equation}\n",
    "$$\n",
    "\n",
    "where $R_{j} x^{\\tau} = \\sum^{j}_{i=1} r_{i} x^{\\tau}$, $d_{j}$ is a variable that represents the uncompounded cumulative return of the portfolio and $r_{f}$ is the risk free rate.\n",
    "\n",
    "Finally, the optimal portfolio is obtained making the transformation $x = y / k$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c85ededb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Weights</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>BAX</th>\n",
       "      <td>0.6007%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>BMY</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CMCSA</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CNP</th>\n",
       "      <td>40.7637%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>CPB</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>GE</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>GOOG</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>MO</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>MSFT</th>\n",
       "      <td>53.4767%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>NI</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SEE</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>T</th>\n",
       "      <td>0.0000%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>TGT</th>\n",
       "      <td>1.4542%</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>VZ</th>\n",
       "      <td>3.7048%</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Weights\n",
       "BAX    0.6007%\n",
       "BMY    0.0000%\n",
       "CMCSA  0.0000%\n",
       "CNP   40.7637%\n",
       "CPB    0.0000%\n",
       "GE     0.0000%\n",
       "GOOG   0.0000%\n",
       "MO     0.0000%\n",
       "MSFT  53.4767%\n",
       "NI     0.0000%\n",
       "SEE    0.0000%\n",
       "T      0.0000%\n",
       "TGT    1.4542%\n",
       "VZ     3.7048%"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#######################################\n",
    "# Finding the max return/EDaR Portfolio\n",
    "#######################################\n",
    "\n",
    "# Defining initial inputs\n",
    "mu = Y.mean().to_numpy().reshape(1,-1)\n",
    "returns = Y.to_numpy()\n",
    "nav = Y.cumsum().to_numpy()\n",
    "n = returns.shape[0]\n",
    "\n",
    "# Defining initial variables\n",
    "w = cp.Variable((mu.shape[1], 1))\n",
    "k = cp.Variable((1, 1))\n",
    "rf0 = 0\n",
    "alpha = 0.05\n",
    "ret = mu @ w\n",
    "X1 = nav @ w\n",
    "\n",
    "# Drawdown Variables\n",
    "d = cp.Variable((nav.shape[0] + 1, 1))\n",
    "constraints = [d[1:] >= X1,\n",
    "               d[1:] >= d[:-1],\n",
    "               d[1:] >= 0,\n",
    "               d[0] == 0]\n",
    "\n",
    "# Entropic Drawdown at Risk Model Variables\n",
    "t = cp.Variable((1, 1))\n",
    "z = cp.Variable((1, 1), nonneg=True)\n",
    "ui = cp.Variable((n, 1))\n",
    "constraints += [cp.sum(ui) <= z,\n",
    "                cp.constraints.ExpCone(d[1:] - X1 - t, np.ones((n, 1)) @ z, ui)] # Exponential cone constraint\n",
    "\n",
    "# Budget and weights constraints\n",
    "constraints += [cp.sum(w) == k,\n",
    "                ret - rf0 * k == 1,\n",
    "                w >= 0,\n",
    "                k >= 0]\n",
    "\n",
    "# Defining risk objective\n",
    "risk = t + z * np.log(1 / (alpha * n))\n",
    "objective = cp.Minimize(risk)\n",
    "\n",
    "# Solving problem\n",
    "prob = cp.Problem(objective, constraints)\n",
    "prob.solve()\n",
    "\n",
    "# Showing Optimal Weights\n",
    "weights = pd.DataFrame(w.value/k.value, index=assets, columns=['Weights'])\n",
    "display(weights)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "de8cc7f7",
   "metadata": {},
   "source": [
    "For more portfolio optimization models and applications, you can see the CVXPY based library __[Riskfolio-Lib](https://github.com/dcajasn/Riskfolio-Lib)__."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
